package com.java.framework.utils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang3.StringUtils;

public class SimpleExpression<T> implements Criterion<T> {

	private String fieldName;       //属性名  
    private Object value;           //对应值  
    private Operator operator;      //计算符
    
    protected SimpleExpression(String fieldName, Object value, Operator operator) {  
        this.fieldName = fieldName;  
        this.value = value;  
        this.operator = operator;  
    }
  
    public String getFieldName() {
        return fieldName;  
    }  
    public Object getValue() {
        return value;  
    }  
    public Operator getOperator() {
        return operator;  
    }
    
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
		Path expression = null;
		if(fieldName.contains(".")){
			String[] names = StringUtils.split(fieldName, "\\.");  
            expression = root.get(names[0]);  
            for (int i = 1; i < names.length; i++) {  
                expression = expression.get(names[i]);  
            }
		} else {
			expression = root.get(fieldName);
		}
		
		switch(operator){
		case EQ:
			if(value == null)
				return cb.isNull(expression);
            return cb.equal(expression, value);
        case NE:
        	if(value == null)
        		return cb.isNotNull(expression);
            return cb.notEqual(expression, value);
        case LIKE:
        	if(value != null) {
        		return cb.like((Expression<String>) expression, value.toString());
        	}
        	return null;
        case IN:
        	if(value != null)
        		return cb.in(expression).value(value);
        	return null;
        case NIN:
        	if(value != null)
        		return cb.not(cb.in(expression).value(value));
        	return null;
        case LT:
        	if(value != null)
        		return cb.lessThan(expression, (Comparable) value);
        	return null;
        case GT:
        	if(value != null)
        		return cb.greaterThan(expression, (Comparable) value);
        	return null;
        case LE:
        	if(value != null)
        		return cb.lessThanOrEqualTo(expression, (Comparable) value);
        	return null;
        case GE:
        	if(value != null)
        		return cb.greaterThanOrEqualTo(expression, (Comparable) value);
        	return null;
        default:
            return null;
		}
	}

	@Override
	public String toString() {
		return fieldName + operator.name() + value ;
	}
}
